﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

namespace JYH.Data
{
    /// <summary>
    /// IMapper provides a way to hook into PetaJYH's Database to JYH mapping mechanism to either
    /// customize or completely replace it.
    /// </summary>
    /// <remarks>
    /// To use this functionality, instantiate a class that implements IMapper and then pass it to
    /// PetaJYH through the static method Mappers.Register()
    /// </remarks>
    public interface IMapper
    {
        /// <summary>
        /// Get information about the table associated with a JYH class
        /// </summary>
        /// <param name="JYHType"></param>
        /// <returns>A TableInfo instance</returns>
        /// <remarks>
        /// This method must return a valid TableInfo.  
        /// To create a TableInfo from a JYH's attributes, use TableInfo.FromJYH
        /// </remarks>
        TableInfo GetTableInfo(Type JYHType);

        /// <summary>
        /// Get information about the column associated with a property of a JYH
        /// </summary>
        /// <param name="JYHProperty">The PropertyInfo of the property being queried</param>
        /// <returns>A reference to a ColumnInfo instance, or null to ignore this property</returns>
        /// <remarks>
        /// To create a ColumnInfo from a property's attributes, use PropertyInfo.FromProperty
        /// </remarks>
        ColumnInfo GetColumnInfo(PropertyInfo JYHProperty);

        /// <summary>
        /// Supply a function to convert a database value to the correct property value
        /// </summary>
        /// <param name="TargetProperty">The target property</param>
        /// <param name="SourceType">The type of data returned by the DB</param>
        /// <returns>A Func that can do the conversion, or null for no conversion</returns>
        Func<object, object> GetFromDbConverter(PropertyInfo TargetProperty, Type SourceType);

        /// <summary>
        /// Supply a function to convert a property value into a database value
        /// </summary>
        /// <param name="SourceProperty">The property to be converted</param>
        /// <returns>A Func that can do the conversion</returns>
        /// <remarks>
        /// This conversion is only used for converting values from JYH's that are 
        /// being Inserted or Updated.  
        /// Conversion is not available for parameter values passed directly to queries.
        /// </remarks>
        Func<object, object> GetToDbConverter(PropertyInfo SourceProperty);
    }
}
